package com.sojson.util;

import static com.sojson.util.cache.CacheUtil.CACHE_REDIS;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.sojson.dao.impl.DictDataDaoImpl;
import com.sojson.entity.po.DictData;

/**
 * 字典工具类
 *
 * @author lzlg
 */
public class DictUtil {

    /** 字典缓存集合在缓存中的名字 */
    public static final String MAP_KEY = "DICT_PARAM_MAP:";
    /** 分隔符 */
    public static final String SEPARATOR = ",";

    /**
     * 加载字典缓存
     * 
     * @param key
     * @throws IOException 
     */
    public static void load() throws IOException {
        DictDataDaoImpl dataDaoImpl = SpringUtil.getBeanByType(DictDataDaoImpl.class);
        put(dataDaoImpl.listAll());
    }

    /**
     * 设置字典缓存
     *
     * @param mapKey    参数键
     * @param val       字典数据
     * @throws IOException 
     */
    public static void put(String mapKey, DictData val) throws IOException {
        put(mapKey, val.getId().toString(), val);
    }

    /**
     * 设置字典缓存
     *
     * @param mapKey    参数键
     * @param key       字典数据键
     * @param val       字典数据值
     * @throws IOException 
     */
    public static void put(String mapKey, String key, Object val) throws IOException {
        CACHE_REDIS.setByMap(getCacheKey(mapKey), key, val);
    }

    /**
     * 设置字典缓存
     * 
     * @param vals
     * @throws IOException 
     */
    public static void put(List<DictData> vals) throws IOException {
        Map<String, List<DictData>> hashMap = new HashMap<>();
        for (DictData dictData : vals) {
            String code = dictData.getCode();
            List<DictData> list = hashMap.get(code);
            if (StringUtil.isBlankObject(list)) {
                list = new ArrayList<>();
                hashMap.put(code, list);
            }

            list.add(dictData);
        }

        Set<Entry<String, List<DictData>>> entrySet = hashMap.entrySet();
        for (Entry<String, List<DictData>> entry : entrySet) {
            put(entry.getKey(), entry.getValue());
        }
    }

    /**
     * 设置字典缓存
     *
     * @param mapKey    参数键
     * @param vals      字典数据列表
     * @throws IOException 
     */
    public static void put(String mapKey, List<DictData> vals) throws IOException {
        Map<String, Object> hashMap = new HashMap<>();
        for (DictData val : vals) {
            hashMap.put(val.getId().toString(), val);
        }

        put(mapKey, hashMap);
    }

    /**
     * 设置字典缓存
     * 
     * @param mapKey
     * @param vals
     * @throws IOException 
     */
    public static void put(String mapKey, Map<String, Object> vals) throws IOException {
        CACHE_REDIS.setByMap(getCacheKey(mapKey), vals);
    }

    /**
     * 删除字典缓存
     * 
     * @param mapKey
     * @param keys
     * @throws IOException 
     */
    public static void del(String mapKey, String... keys) throws IOException {
        CACHE_REDIS.delByMapKey(getCacheKey(mapKey), keys);
    }

    /**
     * 获取字典缓存
     * 
     * @param mapKey
     * @return
     * @throws IOException 
     */
    public static Map<String, DictData> gets(String mapKey) throws IOException {
        return CACHE_REDIS.getMap(getCacheKey(mapKey), DictData.class);
    }

    /**
     * 获取字典缓存
     * 
     * @param mapKey
     * @return
     * @throws IOException 
     */
    public static List<DictData> getList(String mapKey) throws IOException {
        Map<String, DictData> gets = gets(mapKey);
        return new ArrayList<>(gets.values());
    }

    /**
     * 根据字典类型和字典值获取字典标签
     *
     * @param dictType  字典类型
     * @param dictValue 字典值
     * @return 字典标签
     * @throws IOException 
     */
    public static String getDictLabel(String dictType, String dictValue) throws IOException {
        return getDictLabel(dictType, dictValue, SEPARATOR);
    }

    /**
     * 根据字典类型和字典标签获取字典值
     *
     * @param dictType  字典类型
     * @param dictLabel 字典标签
     * @return 字典值
     * @throws IOException 
     */
    public static String getDictValue(String dictType, String dictLabel) throws IOException {
        return getDictValue(dictType, dictLabel, SEPARATOR);
    }

    /**
     * 根据字典类型和字典值获取字典标签
     *
     * @param dictType  字典类型
     * @param dictValue 字典值
     * @param separator 分隔符
     * @return 字典标签
     * @throws IOException 
     */
    public static String getDictLabel(String dictType, String dictValue, String separator) throws IOException {
        StringBuilder propertyString = new StringBuilder();
        List<DictData> datas = getList(dictType);

        if (StringUtil.containsAny(separator, dictValue) && StringUtil.isNotBlank(datas)) {
            for (DictData dict : datas) {
                for (String value : dictValue.split(separator)) {
                    if (value.equals(dict.getValue())) {
                        propertyString.append(dict.getName() + separator);
                        break;
                    }
                }
            }
        } else {
            for (DictData dict : datas) {
                if (dictValue.equals(dict.getValue())) {
                    return dict.getName();
                }
            }
        }
        return StringUtil.stripEnd(propertyString.toString(), separator);
    }

    /**
     * 根据字典类型和字典标签获取字典值
     *
     * @param dictType  字典类型
     * @param dictLabel 字典标签
     * @param separator 分隔符
     * @return 字典值
     * @throws IOException 
     */
    public static String getDictValue(String dictType, String dictLabel, String separator) throws IOException {
        StringBuilder propertyString = new StringBuilder();
        List<DictData> datas = getList(dictType);

        if (StringUtil.containsAny(separator, dictLabel) && StringUtil.isNotBlank(datas)) {
            for (DictData dict : datas) {
                for (String label : dictLabel.split(separator)) {
                    if (label.equals(dict.getName())) {
                        propertyString.append(dict.getValue() + separator);
                        break;
                    }
                }
            }
        } else {
            for (DictData dict : datas) {
                if (dictLabel.equals(dict.getName())) {
                    return dict.getValue();
                }
            }
        }
        return StringUtil.stripEnd(propertyString.toString(), separator);
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    public static String getCacheKey(String configKey) {
        return MAP_KEY + configKey;
    }

}